home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
17 Bit Software 3: The Continuation
/
17-Bit_The_Continuation_Disc.iso
/
amigan
/
amigan 20
/
jimutils
/
dfree.a
< prev
next >
Wrap
Text File
|
1994-01-27
|
8KB
|
307 lines
* DFree.a: An assembler disk free space lister. I came up with this
* as a protest against INFO. I don't CARE how many blocks
* are free, I want to know how much space I've got in BYTES,
* considering everything else tells me file sizes in bytes,
* etc., etc.
*
* Working version finished 12/14/86 jec
* Added support for volume name 12/16/86 jec
*
* Included equate files.
* -----------------------------------------------------------------------
NOLIST
INCLUDE 'exec/types.i'
INCLUDE 'exec/libraries.i'
INCLUDE 'exec/memory.i'
INCLUDE 'libraries/dos.i'
INCLUDE 'libraries/dosextens.i'
INCLUDE 'offsets/exec.i'
INCLUDE 'offsets/dos.i'
LIST
ifd CAPE
EXEOBJ
objfile 'ram:DFree'
optimon -1
endc
* Local Equates
* ------------------------------------------------------------------------
TRUE EQU -1
FALSE EQU 0
RAM EQU 'RAM'<<8
* Stack frame variables
* ------------------------------------------------------------------------
v_STRPTR EQU -128
v_SIZE EQU -124
v_STRING EQU -120
v_OUTPUT EQU -88
* The code segment
* -------------------------------------------------------------------------
link a4,#-128
jsr argtrim ; clean up command line
MOVEM.L D0/A0-A2,-(SP) ; Save command line (OpenLibrary trashes).
moveq #0,d0
;------ get Exec's library base pointer:
LEA.L DOSName(PC),A1 ; name of dos library
moveq #33,d0 ; at LEAST AmigaDOS 1.2
move.l _AbsExecBase,a6
Call OpenLibrary
MOVE.L D0,A6 ; Save library pointer (always in A6).
BNE.S gotdos
; Should really issue an alert here...
moveq #RETURN_FAIL,D0 ; give up
bra FINISHED
gotdos:
; REGISTER USAGE:
; A0 = scratch after command line used.
; A4 = stack frame
; A5 = InfoData address
; A6 = dos library base pointer
; D1-3 = AmigaDOS scratch argument registers
; D4 = current directory lock
; D5 = output handle
; D6 = root lock flag
* Obtain the output handle (needed for write)
Call Output
MOVE.L D0,D5 ; Save for the write
MOVEM.L (SP)+,D0/A0-A2 ; restore command line etc.
* Setup D6 as the restore directory flag
moveq #FALSE,D6
* Now check if we have an argument. If we have, attempt to lock it.
* Otherwise, go for current directory.
cmpi.b #0,(A0) ; a null string for an argument ?
beq.s CURDIR ; yes
; Lock to specified directory. Place name in D1, access mode in D2
move.l a0,d1
move.l #ACCESS_READ,d2
Call Lock
move.l d0,d4 ; remember for later
beq nolock ; did we get a lock?
bra.s uselock ; for the Examine
CURDIR:
; Get lock to current directory. The most bulletproof way of doing this
; (due to bugs in the V1.1 RAM: handler) is to make the root directory
; the current one, because CurrentDir will return the old lock value.
moveq #0,D1
Call CurrentDir ; got the lock
move.l d0,d4 ; for later
moveq #TRUE,d6 ; remember to cd
uselock:
; A lock in D1 and a InfoData address in D2 are all that are needed.
; We allocmem the InfoData to assure alignment.
move.l #id_SIZEOF,D0 ; size of the block
move.l #MEMF_PUBLIC,D1 ; memory requirement
MOVEM.L D2-D7/A0-A6,-(SP) ; in case AllocMem trashes (it does...)
move.l _AbsExecBase,a6
Call AllocMem ; args D0, D1 returns into D0
MOVEM.L (SP)+,D2-D7/A0-A6 ; restore registers
move.l d0,a5 ; save it for later
beq nomem ; but did it work?
move.l d0,d2 ; InfoData address
move.l d4,d1 ; the lock
Call Info ; see what the lock corresponds to.
cmpi.l #FALSE,d0 ; don't need to cd in cleanup code
beq noinfo
move.l d2,a0 ; infodata pointer into a0
move.l id_NumBlocks(a0),d2 ; # of blocks on disk
sub.l id_NumBlocksUsed(a0),d2 ; # already used
moveq #0,d0
move.l d0,d1 ; initialize multiplier
move.l id_BytesPerBlock(a0),d1
subq.l #1,d1 ; adjust for loop
1$:
add.l d2,d0 ; add to total
dbra d1,1$ ; loop 'til done
move.l d0,v_SIZE(a4) ; save for print
tst.l id_VolumeNode(a0) ; ...RAM: doesn't have a Volume
bne.s df1 ; ...Node, so returns 0.
move.l #RAM,v_STRING(a4) ; store RAM name in output string
bra.s df2
df1:
move.l id_VolumeNode(a0),d0 ; here goes a mess caused by
asl.l #2,d0 ; ...using BPTRs to show where
move.l d0,a0 ; ...things are. We need all
move.l 40(a0),d0 ; ...of this mess just to find
asl.l #2,d0 ; ...the Volume Name for the
move.l d0,a0 ; ...requested drive.
moveq #0,d0
move.b (a0)+,d0 ; get length of Volume name
move.l a4,d1 ; and find
add.l #v_STRING,d1 ; ...where to store it
move.l d1,a1
move.l d1,v_STRPTR(a4) ; ...(also, save for RawDoFmt)
dlp:
move.b (a0)+,(a1)+ ; copy name to string storage
dbra d0,dlp
move.b #0,(a1) ; ...and remember to NULL term!
df2:
lea FMT(pc),a0 ; ...the format string
lea v_STRPTR(a4),a1 ; ...the first print parm
lea store(pc),a2 ; ...the storage routine address
lea v_OUTPUT(a4),a3 ; ...the storage area
movem.l a3/a6,-(sp) ; save a couple registers
move.l _AbsExecBase,a6
Call RawDoFmt ; and figure it out!
movem.l (sp)+,a3/a6
move.l d5,d1
move.l a3,d2
moveq #127,d0
moveq #0,d3
lenloop:
tst.b (a3)+ ; look for null term
beq.s printit
addq.l #1,d3
dbra d0,lenloop
printit:
Call Write ; then print when found
bra.s cleanup ; and quit.
nomem:
move.l d5,d1
move.l #S_NOMEM,d2
move.l #S_NOMSIZ,d3
Call Write
bra.s afterfree
noinfo:
move.l d5,d1
move.l #S_NOINFO,d2
move.l #S_NINFSIZ,d3
Call Write
bra.s cleanup
nolock:
move.l d5,d1
move.l #S_NLOCK,d2
move.l #S_NLKSIZ,d3
Call Write
bra.s FINISHED
cleanup:
; start off by freeing allocated memory.
move.l a5,a1
MOVEM.L D1-D7/A0-A6,-(SP) ; in case FreeMem trashes
move.l #id_SIZEOF,D0
move.l _AbsExecBase,a6
Call FreeMem
MOVEM.L (SP)+,D1-D7/A0-A6 ; restore registers
afterfree:
; May have to throw away two locks and do a cd here
move.l d4,d1
cmpi.l #FALSE,d6
beq.s nocd
Call CurrentDir ; get back to where we were
move.l d0,d1
nocd:
Call UnLock
moveq #RETURN_OK,D0
FINISHED:
unlk a4
rts
* Subroutines
* ------------------------------------------------------------------------
********************************************************************************
* argtrim: a routine to trim the end of a command line and null terminate
* it. This is achieved in the following manner:
* Start at the end and run back until a non-whitespace (nl/blank)
* character is encountered. If this is a quote, toss it.
* If the *first* character is a quote, bump the start address by
* one. No pretense of quote matching here.
* Inputs: address in A0, length in D0
* Outputs: address in A0.
********************************************************************************
argtrim:
movem.l d1-d7/a1-a6,-(sp) ; save registers
cmpi.b #'"',(a0) ; starts with a quote?
bne.s checkline ; no
subq #1,d0 ; yes - decrement count
addq #1,a0 ; and bump start address
checkline:
cmpi.b #1,D0 ; length includes the newline
bne.s isline ; yes - there is something there
move.b #0,(a0) ; create null string
bra.s argfini ; done
isline:
; strip off any run of blanks on the end...
move.l a0,a1 ; computing end address of line
add.l d0,a1 ;
subq #2,a1 ;
toploop:
cmp.l a0,a1
beq.s empty ; single char or run of blanks
cmpi.b #' ',(a1)
bne.s endloop ; finished the scan
subq #1,a1 ; else back one more
bra.s toploop ; and try again
endloop:
cmpi.b #'"',(a1)
beq.s nullit
nullnext:
addq #1,a1
nullit:
move.b #0,(a1)
bra.s argfini
empty: ; could be blanks or a single char
cmpi.b #' ',(a1)
bne.s endloop ; or maybe a single quote!
move.b #0,(a0)
argfini:
movem.l (sp)+,d1-d7/a1-a6 ; restore registers
rts
********************************************************************************
* STORE: routine used by _LVORawDoFmt to store output string
********************************************************************************
store:
move.b d0,(a3)+
rts
********************************************************************************
* Data declarations
********************************************************************************
CNOP 0,4
DOSName DOSNAME
S_NLOCK DC.B 'directory or file name not found',10
S_NLKSIZ equ *-S_NLOCK
S_NOINFO DC.B 'Couldn''t get info for disk',10
S_NINFSIZ equ *-S_NOINFO
S_NOMEM DC.B 'No memory',10
S_NOMSIZ equ *-S_NOMEM
FMT DC.B 'Volume "%s:" has %ld bytes free.',10,0
END